package com.tsingteng.cosfun.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;

/**
 * 上传图片、压缩图片
 *
 * @author zhikuan
 *
 */
public class UploadBitmapUtil {
    public static String end = "\r\n";
    public static String twoHyphens = "--";
    public static String boundary = "*****";
    private static final int TIME_OUT = 10 * 10000000; // 超时时间
    public static final int SUCCESS = 100;
    public static final int FILE_NOT_FOUND = 101;
    public static final int IO_EXCEPTION = 102;
    public static final int GEN_BITMAP_FAILURE = 103;
    public static final int RESOLUTION_NOT_DEFINE = 104;
    public static CompressFormat format = CompressFormat.JPEG;
    public static int compressedSize = 100;
    public static String imageUrlName = "url";
    public static final int IMAGE_NOT_COMRESS = 1;
    public static final int SMALL_IMAGE_COMPRESS = 0;

    //把压缩后的位图上传到服务器中
//	public static String upload(Bitmap bitmap, String urlAddress, String imageName) {
//		return upload(bitmap, null, urlAddress, imageName);
//	}
    //通过本地图片的地址上传到服务器
    public static String upload(String imageAddress, String urlAddress,
                                String imageName) {
        return upload(null, imageAddress, urlAddress, imageName);
    }

    //上传图片到服务器中
    public static String upload(Bitmap bitmap, String imageAddress,
                                String urlAddress, String imageName) {
        // 如果Bitmap和Image都传过来的话，就把Bitmap置为空
        if (bitmap != null && imageAddress != null) {
            bitmap = null;
        }
        if (bitmap == null && imageAddress == null) {
            return null;
        }
        DataOutputStream ds;
        FileInputStream fStream = null;
        try {
            URL url = new URL(urlAddress);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(TIME_OUT);
            conn.setReadTimeout(TIME_OUT);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);

            ds = new DataOutputStream(conn.getOutputStream());
            ds.writeBytes(twoHyphens + boundary + end);
            ds.writeBytes("Content-Disposition: form-data; "
                    + "name=\"img\";filename=\"" + imageName + "\"" + end);
            ds.writeBytes(end);
            if (imageAddress != null) {
                fStream = new FileInputStream(imageAddress);
                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int length = -1;
                while ((length = fStream.read(buffer)) != -1) {
                    ds.write(buffer, 0, length);
                }
            }
            ds.writeBytes(end);
            ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
            //flush之后，把数据传到了服务器中
            ds.flush();
            //如果返回的为200，表示上传成功
            if (conn.getResponseCode() == 200) {
                //成功后把服务器返回的Json解析
                InputStream is = conn.getInputStream();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] b = new byte[1024];
                int len;
                while ((len = is.read(b)) != -1) {
                    bos.write(b, 0, len);
                }
                is.close();
                return bos.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fStream != null) {
                try {
                    fStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    //这个是质量压缩
    public static int qualityCompress(String imageAddress, String saveAddress, int scale) {
        return compress(imageAddress, saveAddress, IMAGE_NOT_COMRESS);
    }

    //这个是边界压缩
    public static int boundaryCompress(String imageAddress, String saveAddress, int width, int height, int scale) {
        return compress(imageAddress, saveAddress, width, height, SMALL_IMAGE_COMPRESS, 100);
    }

    public static int compress(String imageAddress, String saveAddress, int width, int height, int scale, int boudaryScale) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imageAddress, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;
        //如果scale为0，表示自己指定图片压缩的比例
        if (scale != SMALL_IMAGE_COMPRESS) {
            if (scale > IMAGE_NOT_COMRESS) {
                be = scale;
            }
        } else {
            float screenHeight = (float) height;
            float screenWidth = (float) width;
            if (w > h && w > screenWidth) {
                be = (int) (newOpts.outWidth / screenWidth);
                // be = (int) ((w / screenWidth + h / screenWidth) / 2) ;
            } else if (w < h && h > screenHeight) {
                be = (int) (newOpts.outHeight / screenHeight);
                // be = (int) ((w / screenHeight + h / screenHeight) / 2) ;
            } else if (w == h && w > screenHeight) {
                be = (int) (newOpts.outWidth / screenWidth);
            }
        }
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        newOpts.inSampleSize = be;
        Bitmap bitmap = BitmapFactory.decodeFile(imageAddress, newOpts);
        if (bitmap != null) {
            try {
                //因为位图对象的compress方法不可以把位图写入到ds中，所以先存入本地，再取出来
                OutputStream os = new FileOutputStream(new File(saveAddress));
                bitmap.compress(format, boudaryScale, os);
                os.close();
                return SUCCESS;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return FILE_NOT_FOUND;
            } catch (IOException e) {
                e.printStackTrace();
                return IO_EXCEPTION;
            }
        } else {
            return GEN_BITMAP_FAILURE;
        }
    }

    public static int compress(String imageAddress, String saveAddress, int scale) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imageAddress, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;
        //如果scale为0，表示自己指定图片压缩的比例
        if (scale != SMALL_IMAGE_COMPRESS) {
            if (scale > IMAGE_NOT_COMRESS) {
                be = scale;
            }
        } else {
            float screenHeight = 480f;
            float screenWidth = 480f;
            if (w > h && w > screenWidth) {
                be = (int) (newOpts.outWidth / screenWidth);
                // be = (int) ((w / screenWidth + h / screenWidth) / 2) ;
            } else if (w < h && h > screenHeight) {
                be = (int) (newOpts.outHeight / screenHeight);
                // be = (int) ((w / screenHeight + h / screenHeight) / 2) ;
            } else if (w == h && w > screenHeight) {
                be = (int) (newOpts.outWidth / screenWidth);
            }
        }
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        newOpts.inSampleSize = be;
        Bitmap bitmap = BitmapFactory.decodeFile(imageAddress, newOpts);
        if (bitmap != null) {
            try {
                //因为位图对象的compress方法不可以把位图写入到ds中，所以先存入本地，再取出来
                OutputStream os = new FileOutputStream(new File(saveAddress));
                bitmap.compress(format, 25, os);
                os.close();
                return SUCCESS;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return FILE_NOT_FOUND;
            } catch (IOException e) {
                e.printStackTrace();
                return IO_EXCEPTION;
            }
        } else {
            return GEN_BITMAP_FAILURE;
        }
    }

    public static int compress(String imageAddress, String saveAddress, int screenWidth, int screenHeight) {
        try {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(imageAddress, newOpts);
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            newOpts.inJustDecodeBounds = false;
            int inSampleSize = 1;
            float sw = w / Float.parseFloat(String.valueOf(screenWidth));
            float sh = h / Float.parseFloat(String.valueOf(screenHeight));
            if (sh > 1.0 && sw > 1.0) {
                inSampleSize = Math.round(Math.min(sw, sh));
            }
            newOpts.inSampleSize = inSampleSize;
            Bitmap bmp = BitmapFactory.decodeFile(imageAddress, newOpts);
            //将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bmp.compress(CompressFormat.JPEG, 100, baos);
            byte[] b = baos.toByteArray();
            //将字节换成KB
            int mid = b.length / 1024;
            int maxsize = 400;
            int size = maxsize * 100 / mid;

            try {
                //因为位图对象的compress方法不可以把位图写入到ds中，所以先存入本地，再取出来
                OutputStream os = new FileOutputStream(new File(saveAddress));
                if (size > 100) {
                    bmp.compress(format, 100, os);
                } else {
                    bmp.compress(format, size, os);
                }
                os.close();
                return SUCCESS;
            } catch (Exception e) {
                e.printStackTrace();
                return FILE_NOT_FOUND;
            }  finally {
                if (bmp != null && !bmp.isRecycled()) {
                    bmp.recycle();
                    bmp = null;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return FILE_NOT_FOUND;
        }

    }

    //参数是一个Bitmap
    public static Bitmap compress(Bitmap bitmap, int scale) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(format, 100, bos);
        byte[] byteArray = bos.toByteArray();
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;

        int be = scale;
        if (scale != 0) {
            be = scale;
        } else {
            float screenHeight = 160f;
            float screenWidth = 160f;
            if (be <= 0) {
                be = 1;
            }
            if (w > h && w > screenWidth) {
                be = (int) (newOpts.outWidth / screenWidth);
                // be = (int) ((w / screenWidth + h / screenWidth) / 2) ;
            } else if (w < h && h > screenHeight) {
                be = (int) (newOpts.outHeight / screenHeight);
                // be = (int) ((w / screenHeight + h / screenHeight) / 2) ;
            } else if (w == h && w > screenHeight) {
                be = (int) (newOpts.outWidth / screenWidth);
            }
        }
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        newOpts.inSampleSize = be;
        bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, newOpts);
        return bitmap;
    }

    public static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(format, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > compressedSize) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            image.compress(format, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }
}
